home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
emulator
/
bsvc-1.000
/
bsvc-1
/
bsvc-1.0.4
/
src
/
Assemblers
/
hecasm
/
asm3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-26
|
5KB
|
350 lines
/* this file contains the lexical functions and symbol table management */
/* routines */
#include "asm.h"
/*
* Get the next non white
* character.
*/
getnb()
{
register int c;
while(((c = getraw()) == ' ') || (c == '\t'));
return(c);
}
/*
* Get next character from
* the input.
* Apply string mappings.
*/
getmap()
{
register int n, c, v;
if((c=getraw()) == '\\')
switch(c = getraw())
{
case 'n':
c = '\n';
break;
case 'r':
c = '\r';
break;
case 't':
c = '\t';
break;
case 'b':
c = '\b';
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
v = n = 0;
while(++n<=3 && c>='0' && c<='7')
{
v = 8*v + c - '0';
c = getraw();
}
putback(c);
c = v;
break;
default:
putback(c);
c = '\\';
}
return(c);
}
/*
* Get next character.
* Basic routine.
* Don't goof up on end of
* line.
*/
getraw()
{
register int c;
if((c = *sptr) != '\n')
++sptr;
else
return('\0');
return(c);
}
/*
* Check for alpha.
*/
alpha(c)
register int c;
{
if(c=='.' || c=='_' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
return(1);
return(0);
}
getnum(c)
int c;
{
char id[NCPS];
int i;
i = 0;
do
{
id[i++] = c;
}
while(isdigit(c=getnb()));
putback(c);
id[i] = '\0';
sscanf(id,"%d",&i);
return(i);
}
/*
* Put a character back.
* A line at a time version
* of ungetc.
* Die if too many characters
* are put back.
*/
putback(c)
{
if(c != '\0')
if(--sptr < sbuf)
exit(1);
}
/*
* Read in an indentifier.
* Store it (padded with nulls) into the
* supplied buffer.
*/
getid(c, id)
register int c;
char *id;
{
register char *p;
p = id;
while(alpha(c) || (c>='0' && c<='9') || c == '$')
{
if(p < &id[NCPS-1])
*p++ = c;
c = getraw();
}
*p = '\0';
putback(c);
}
/* convert a string to all lower case */
lowerconv(str)
char *str;
{
while (*str != '\0')
{
if (*str >= 'A' && *str <= 'Z')
*str = *str - 'A' + 'a';
str++;
}
}
/* lookup a symbol in the permanent symbol table. This is a binary search */
struct sym *pstlookup(id)
char *id;
{
int middle, left, right;
int r;
left = 0;
right = pstsize - 1;
middle = (left + right)/2;
while((r = comp(id,pst[middle].s_name)) != 0)
{
if (r > 0)
left = middle + 1;
else
right = middle - 1;
if (left > right)
return(NULL);
middle = (left + right)/2;
}
return(&pst[middle]);
}
/* the user symbol table is a hash table therefore it must be initialized */
/* so that all entries are invalid. We must also put the location */
/* counter in the table */
initust()
{
int i;
struct sym *sp;
for(i=0;i<USERMAX;i++)
ust[i].s_used = FALSE;
sp = ustlookup(".");
dot = sp;
sp->s_used = TRUE;
}
/* user symbol table lookup. If the item is not found create an */
/* entry for it */
struct sym *ustlookup(id)
char *id;
{
register struct sym *stp;
register int s, r;
char *str;
/* compute the hash function */
s = 0;
str = id;
while(*str != '\0')
s += *str++;
s &= USERMAX - 1;
/* start looking for it. We use a linear collision resolution */
if (ust[s].s_used)
if (!same(id,ust[s].s_name))
{
/* set it to false in case the table is full. That way we know */
/* when we wrap around */
ust[s].s_used = FALSE;
r = (s + 1) & (USERMAX - 1);
while ((ust[r].s_used) && (!same(id,ust[r].s_name)))
r = ++r & (USERMAX - 1);
/* wrapped all the way around */
if (r == s)
{
fprintf(stderr,"Symbol Tabel Overflow!\n");
exit(1);
}
else
ust[s].s_used = TRUE;
stp = &ust[r];
}
else
stp = &ust[s];
else
stp = &ust[s];
/* if the symbol already existed */
if (stp->s_used)
{
refgen(stp,lineno);
return(stp);
}
/* insert the symbol in the table */
stp->s_used = TRUE;
copy(stp->s_name, id);
stp->s_type = S_UND;
stp->s_flag = 0;
stp->s_ref = NULL;
stp->s_value = 0;
return(stp);
}
/*
* Record a reference for the symbol
*/
refgen(stp, iline)
register struct sym *stp;
register int iline;
{
if (pass != 1)
return;
if (refptr >= &reftab[REFMAX])
{
fprintf(stderr,"Reference Table Overflow!\n");
exit(1);
}
refptr->r_chain = stp->s_ref;
refptr->r_stmtno = iline;
stp->s_ref = refptr++;
++refcnt;
return;
}
/*
* Compare two names.
* return integer >0 if a1 > a2
* =0 if a1 = a2
* <0 if a1 < a2
*/
comp(a1,a2)
register char *a1, *a2;
{
register int c1,c2;
while((*a1 != '\0') && (*a2 != '\0'))
if((c1 = *a1++) != (c2 = *a2++))
return(c1 - c2);
return (*a1 - *a2);
}
/*
* compare two strings for equality
*/
same(s1,s2)
register char *s1, *s2;
{
while(*s1 == *s2)
{
if (*s1++ == '\0')
return(TRUE);
s2++;
}
return(FALSE);
}
/*
* Copy strings
*/
copy(s1,s2)
register char *s1, *s2;
{
while (*s1++ = *s2++);
return;
}